# -*- coding: utf-8 -*-

"""
  @author: tangliqi
  @date: 2022/12/1 15:55
  @python version: 3.6 
  @contact me: 110
  ---------------------------------------
  @desc: python设计模式实现 => 策略模式.py
"""
from abc import abstractmethod


# 通过一个文件处理的例子来说明。
# 有一个文件处理的通用类，可以处理excel、txt、exe文件。
# 面对不同类型的文件，返回具体对应的文件处理类，也就是具体的策略类。
# 策略模式的构成：1.策略抽象接口类 2.具体策略类
# 当有多个策略时，可以通过简单工厂封装所有的策略，使调用更加易用。

# ============================  策略抽象接口类  ============================
class FileStrategy:
    @abstractmethod
    def read(self):
        pass

    def __repr__(self):
        """"""
        return self.__class__.__name__


# ============================  具体策略类  ============================
class ExeFileStrategy(FileStrategy):

    def read(self):
        print("--- 进行 exe 文件的读取 ---")


class ExeclFileStrategy(FileStrategy):

    def read(self):
        print("--- 进行 excel 文件的读取 ---")


class TxtFileStrategy(FileStrategy):

    def read(self):
        print("--- 进行 txt 文件的读取 ---")


# ============================  策略工厂类  ============================
# 根据策略类是否有状态，可以分为两种策略的生成方式。


# 策略类无状态时，每次返回同一个策略类，主要提供逻辑的计算。
class FileStrategyFactory:
    MAP = {
        "exe": ExeFileStrategy(),
        "execl": ExeclFileStrategy(),
        "txt": TxtFileStrategy(),
    }

    def create(self, key):
        return self.MAP[key]


# 策略类有状态时，每次返回独立的策略对象，策略对象之间独立。
class FileStrategyFactory1:
    MAP = {
        "exe": ExeFileStrategy,
        "execl": ExeclFileStrategy,
        "txt": TxtFileStrategy,
    }

    def create(self, key):
        return self.MAP[key]()


if __name__ == '__main__':
    # 无状态策略类
    fac = FileStrategyFactory()
    exe = fac.create("exe")
    exe1 = fac.create("exe")
    execl = fac.create("execl")
    print(exe is exe1)  # True，每次返回同一个对象
    exe.read()
    execl.read()

    # 有状态策略类
    fac = FileStrategyFactory1()
    exe = fac.create("exe")
    exe1 = fac.create("exe")
    execl = fac.create("execl")
    print(exe is exe1)  # False，每次返回的对象不同
    exe.read()
    execl.read()
